package cn.t.repository.impl.sku;


import cn.t.converter.sku.SkuConverter;
import cn.t.core.mode.PageQueryDTO;
import cn.t.core.repoistory.RepositoryImpl;
import cn.t.model.sku.SkuDO;
import cn.t.persistence.entity.sku.SkuPO;
import cn.t.persistence.mapper.sku.SkuMapper;
import cn.t.repository.sku.SkuRepository;
import cn.t.request.SkuReq;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 商品表(Sku)数据仓库
 *
 * @author t
 * @since 2024-05-24 10:18:11
 */
@Slf4j
@Repository
@AllArgsConstructor
public class SkuRepositoryImpl extends RepositoryImpl<SkuMapper, SkuPO, SkuConverter, SkuDO> implements SkuRepository {


    @Override
    public List<SkuDO> findByModel(SkuDO skuDO, int start, Integer pageSize, String field, String direction) {

        String lastSql = StringUtils.hasText(field) ?
                " order by " + field +" "+ direction + " limit " + start + "," + pageSize
                :
                " limit " + start + "," + pageSize;

        List<SkuPO> list = getWrapper(skuDO).last(lastSql).list();
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }

        return list.stream().map(converter::po2Model).collect(Collectors.toList());
    }

    private LambdaQueryChainWrapper<SkuPO> getWrapper(SkuDO skuDO) {
        LambdaQueryChainWrapper<SkuPO> wrapper = lambdaQuery();
        if (!ObjectUtils.isEmpty(skuDO.getSkuCode())) {
            wrapper.eq(SkuPO::getSkuCode, skuDO.getSkuCode());
        }
        if (!ObjectUtils.isEmpty(skuDO.getSkuName())) {
            wrapper.eq(SkuPO::getSkuName, skuDO.getSkuName());
        }
        if (!ObjectUtils.isEmpty(skuDO.getSkuImg())) {
            wrapper.eq(SkuPO::getSkuImg, skuDO.getSkuImg());
        }
        if (!ObjectUtils.isEmpty(skuDO.getCategoryId())) {
            wrapper.eq(SkuPO::getCategoryId, skuDO.getCategoryId());
        }
        if (!ObjectUtils.isEmpty(skuDO.getStatus())) {
            wrapper.eq(SkuPO::getStatus, skuDO.getStatus());
        }
        if (!ObjectUtils.isEmpty(skuDO.getSize())) {
            wrapper.eq(SkuPO::getSize, skuDO.getSize());
        }
        if (!ObjectUtils.isEmpty(skuDO.getWeight())) {
            wrapper.eq(SkuPO::getWeight, skuDO.getWeight());
        }
        if (!ObjectUtils.isEmpty(skuDO.getQty())) {
            wrapper.eq(SkuPO::getQty, skuDO.getQty());
        }
        if (!ObjectUtils.isEmpty(skuDO.getChargeUnit())) {
            wrapper.eq(SkuPO::getChargeUnit, skuDO.getChargeUnit());
        }
        if (!ObjectUtils.isEmpty(skuDO.getPhysicalUnit())) {
            wrapper.eq(SkuPO::getPhysicalUnit, skuDO.getPhysicalUnit());
        }
        if (!ObjectUtils.isEmpty(skuDO.getDescription())) {
            wrapper.eq(SkuPO::getDescription, skuDO.getDescription());
        }
        if (!ObjectUtils.isEmpty(skuDO.getPSkuCode())) {
            wrapper.eq(SkuPO::getPSkuCode, skuDO.getPSkuCode());
        }
        if (!ObjectUtils.isEmpty(skuDO.getErrorRate())) {
            wrapper.eq(SkuPO::getErrorRate, skuDO.getErrorRate());
        }
        if (!ObjectUtils.isEmpty(skuDO.getGmtModified())) {
            wrapper.between(SkuPO::getGmtModified, skuDO.getGmtModifiedStart(), skuDO.getGmtModifiedEnd());
        }
        if (!ObjectUtils.isEmpty(skuDO.getGmtCreated())) {
            wrapper.between(SkuPO::getGmtCreated, skuDO.getGmtCreatedStart(), skuDO.getGmtCreatedEnd());
        }
        wrapper.in(!CollectionUtils.isEmpty(skuDO.getSkuCodes()), SkuPO::getSkuCode, skuDO.getSkuCodes());
        return wrapper;
    }

    @Override
    public long count(SkuDO skuDO) {
        return getWrapper(skuDO).count();
    }

    @Override
    public List<SkuDO> findModelList(List<String> skus) {
        LambdaQueryWrapper<SkuPO> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(!CollectionUtils.isEmpty(skus), SkuPO::getSkuCode,skus);
        List<SkuPO> skuList=baseMapper.selectList(wrapper);
        return   skuList.stream().map(skuPo->converter.po2Model(skuPo)).collect(Collectors.toList());
    }

    @Override
    public List<SkuDO> querySkuPage(PageQueryDTO<SkuReq> req, String field, String direction) {
        LambdaQueryChainWrapper<SkuPO> wrapper = getWrapper(req.getParam());
        String lastSql = StringUtils.hasText(field) ?
                " order by " + field +" "+ direction + " limit " + req.getStart() + "," + req.getPageSize()
                :
                " limit " + req.getStart() + "," + req.getPageSize();

        List<SkuPO> list = wrapper.last(lastSql).list();
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return list.stream().map(converter::po2Model).collect(Collectors.toList());
    }

    public LambdaQueryChainWrapper<SkuPO> getWrapper(SkuReq reqParam) {
        LambdaQueryChainWrapper<SkuPO> wrapper = lambdaQuery();
        if (null != reqParam) {
            if (!ObjectUtils.isEmpty(reqParam.getSkuCode())) {
                wrapper.eq(SkuPO::getSkuCode, reqParam.getSkuCode());
            }
            if (!ObjectUtils.isEmpty(reqParam.getSkuName())) {
                wrapper.eq(SkuPO::getSkuName, reqParam.getSkuName());
            }
            if (!ObjectUtils.isEmpty(reqParam.getCategoryId())) {
                wrapper.eq(SkuPO::getCategoryId, reqParam.getCategoryId());
            }
            if (!CollectionUtils.isEmpty(reqParam.getSkuCodes())) {
                wrapper.in(SkuPO::getSkuCode, reqParam.getSkuCodes());
            }

            wrapper.in(!CollectionUtils.isEmpty(reqParam.getSkuCodes()), SkuPO::getSkuCode, reqParam.getSkuCodes());
        }
        return wrapper;
    }

    @Override
    public Long querySkuCount(SkuReq param) {
        LambdaQueryChainWrapper<SkuPO> wrapper = getWrapper(param);
        return wrapper.count();
    }

    @Override
    public SkuDO detail(String skuCode) {
        LambdaQueryChainWrapper<SkuPO> wrapper = lambdaQuery();
        wrapper.eq(SkuPO::getSkuCode, skuCode);
        return converter.po2Model(wrapper.one());
    }

    @Override
    public void updateStatus(String skuCode, Integer status) {
        LambdaUpdateChainWrapper<SkuPO> wrapper = lambdaUpdate();
        wrapper.eq(SkuPO::getSkuCode, skuCode);
        wrapper.set(SkuPO::getStatus, status);
        wrapper.update();
    }

    @Override
    public void addOrUpdateBatch(List<SkuDO> skuDOS) {
        if (CollectionUtils.isEmpty(skuDOS)) {
            return;
        }

        List<SkuPO> skuPOS = skuDOS.stream().map(this.converter::model2Po).collect(Collectors.toList());
        this.saveOrUpdateBatch(skuPOS);
    }
}
